package com.ruoyi.network.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.net.NetUtil;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.network.domain.entity.IpRange;
import com.ruoyi.network.enums.BaseStatusEnum;
import com.ruoyi.network.model.vo.IpRangeExcelVO;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

import static com.ruoyi.network.utils.IpRangeUtil.calculateIPRange;
import static com.ruoyi.network.utils.IpRangeUtil.getMaxAllocatableIps;

/**
 * IP段表格工具类抽取
 *
 * @author Administrator
 */
@Component
public class IpRangeExcelUtil {
    @Resource
    private ISysDeptService deptService;

    // 如果需要提供静态方法访问，可以这样做
    private static IpRangeExcelUtil instance;

    @Autowired
    public void setInstance(IpRangeExcelUtil instance) {
        IpRangeExcelUtil.instance = instance;
    }

    /**
     * 通过组织名称列表获取组织对象
     *
     * @param deptNames 组织名称列表
     * @return Map<String, SysDept> 映射结果
     */
    public Map<String, SysDept> findDeptMapByDeptNames(List<String> deptNames) {
        return deptService.findDeptMapByDeptNames(deptNames);
    }

    /**
     * 提供静态使用
     *
     * @param deptNames 组织名称列表
     * @return Map<String, SysDept> 映射结果
     */
    public static Map<String, SysDept> findDeptMapByDeptNamesStatic(List<String> deptNames) {
        if (instance == null) {
            return Collections.emptyMap();
        }
        return instance.findDeptMapByDeptNames(deptNames);
    }

    /**
     * 数据转换器
     *
     * @param vos     待转换数据
     * @param deptMap 数据映射结构
     * @param list    重复IP段数据集
     * @return List<IpRange> 转换结果
     */
    public static List<IpRange> convertIpRangeExcelVO(List<IpRangeExcelVO> vos, Map<String, SysDept> deptMap, List<String> list) {
        if (CollUtil.isEmpty(vos)) {
            return Collections.emptyList();
        }

        List<IpRange> buildResult = new ArrayList<>(vos.size());

        for (IpRangeExcelVO v : vos) {
            if (list.contains(v.getRangeKey())) {
                throw new ServiceException("IP段:" + v.getRangeKey() + "重复");
            }

            SysDept sysDept = deptMap.get(v.getUsageDeptId());

            if (Objects.isNull(sysDept)) {
                throw new ServiceException("使用部门:" + v.getUsageDeptId() + "不存在");
            }

            IpRange ipRange = new IpRange();
            ipRange.setRangeName(v.getRangeKey());
            ipRange.setIpMask(Integer.parseInt(v.getIpMask()));
            ipRange.setUsageBizId(sysDept.getDeptId());
            ipRange.setStatus(BaseStatusEnum.ENABLE);
            ipRange.setFormatName(v.getRangeKey());
            int maxAllocatableIps = getMaxAllocatableIps(ipRange.getRangeName(), ipRange.getIpMask());
            ipRange.setAsgCount(maxAllocatableIps);
            Map<Boolean, String> map = calculateIPRange(ipRange.getFormatName(), ipRange.getIpMask());

            ipRange.setStartIp(NetUtil.ipv4ToLong(Optional.ofNullable(map.get(true)).orElse("")));
            ipRange.setEndIp(NetUtil.ipv4ToLong(Optional.ofNullable(map.get(false)).orElse("")));

            buildResult.add(ipRange);
        }

        return buildResult;
    }
}
